package com.googlecode.lightest.core

import static com.googlecode.lightest.core.RunnerSupport.*

import com.googlecode.lightest.core.LightestTestCase
import org.testng.annotations.*

class ReportGenerationVerifier extends LightestTestCase {
    def resultsFile
    def completedMethods

    ReportGenerationVerifier() {
        resultsFile = new File(OUTPUT_DIR, RESULTS_XML)
        completedMethods = []
    }

    @AfterClass
    void verifyCompletedMethods() {
        assertEquals(4, completedMethods.size())
    }

    /**
     * Given a count of the test methods that have been executed to date, this
     * method verifies the following when the count is non-zero:
     *
     *  1) the result file was created;
     *  2) the result file reports the correct status for each method executed
     *    ("b()" should fail, all others should pass); and
     *  3) the result file reports on all expected methods, and only expected
     *     methods.
     *
     * It essentially introspects the results generated as it is running!
     */
    private void assertMethodCount() {
        if (completedMethods.size() > 0) {
            assertTrue(resultsFile.exists())

            def foundCount = 0
            def root = new XmlParser().parse(resultsFile)

            completedMethods.each { methodName ->
                def node = RunnerTestCase.getTestMethod(root, methodName)

                if (node != null) {
                    if (methodName == 'b') {
                        assertEquals(RunnerTestCase.TEST_FAILED, node.'@status')
                    }
                    else {
                        assertEquals(RunnerTestCase.TEST_PASSED, node.'@status')
                    }
                    ++foundCount
                }
            }

            assertEquals(completedMethods.size(), foundCount)
        }
    }

    @Test
    void a() {
        assertMethodCount()
        completedMethods << 'a'
    }

    @Test
    void b() {
        // don't assert here - this method fails in any case, so an assertion
        // failure could not be distinguished
        completedMethods << 'b'
        fail()
    }

    @Test
    void c() {
        assertMethodCount()
        completedMethods << 'c'
    }

    @Test
    void d() {
        assertMethodCount()
        completedMethods << 'd'
    }
}
